import { Injectable } from '@nestjs/common';
import { WeixinUser, WeixinUserCreationAttributes } from 'src/dao/WeixinUser';
import { Performance } from 'src/common/decorators/performance.decorator';
import sequelize from 'src/util/sequelize';
import { uuid } from 'uuidv4';

export interface CreateWeixinUserDto {
  openid: string;
  sessionKey?: string;
  unionid?: string;
  nickname?: string;
  avatarUrl?: string;
  gender?: number;
  country?: string;
  province?: string;
  city?: string;
  language?: string;
  phone?: string;
  deviceInfo?: object;
}

@Injectable()
export class WeixinUserService {
  private weixinUser: typeof WeixinUser;

  constructor() {
    this.weixinUser = WeixinUser.initModel(sequelize);
  }

  /**
   * 根据openid查找用户
   */
  async findByOpenid(openid: string): Promise<WeixinUser | null> {
    return await this.weixinUser.findOne({
      where: { openid },
    });
  }

  /**
   * 创建新的微信用户
   */
  async create(userData: CreateWeixinUserDto): Promise<WeixinUser> {
    const userCreateData: WeixinUserCreationAttributes = {
      id: uuid(),
      openid: userData.openid,
      sessionKey: userData.sessionKey,
      unionid: userData.unionid,
      nickname: userData.nickname || '微信用户',
      avatarUrl: userData.avatarUrl,
      gender: userData.gender || 0,
      country: userData.country || 'China',
      province: userData.province,
      city: userData.city,
      language: userData.language || 'zh_CN',
      phone: userData.phone,
      status: 1,
      loginCount: 1,
      lastLoginTime: new Date(),
      deviceInfo: userData.deviceInfo,
      createdTime: new Date(),
      updatedTime: new Date(),
    };

    return await this.weixinUser.create(userCreateData);
  }

  /**
   * 更新用户登录信息
   */
  async updateLoginInfo(
    openid: string,
    sessionKey?: string,
    deviceInfo?: object,
  ): Promise<WeixinUser | null> {
    const user = await this.findByOpenid(openid);
    if (!user) {
      return null;
    }

    // 更新登录信息
    await user.update({
      sessionKey: sessionKey || user.sessionKey,
      lastLoginTime: new Date(),
      loginCount: user.loginCount + 1,
      deviceInfo: deviceInfo || user.deviceInfo,
      updatedTime: new Date(),
    });

    return user.reload();
  }

  /**
   * 查找或创建用户（微信登录时使用）- 优化版本使用 UPSERT
   */
  @Performance('数据库用户查找或创建')
  async findOrCreateUser(userData: CreateWeixinUserDto): Promise<WeixinUser> {
    const userCreateData: WeixinUserCreationAttributes = {
      id: uuid(),
      openid: userData.openid,
      sessionKey: userData.sessionKey,
      unionid: userData.unionid,
      nickname: userData.nickname || '微信用户',
      avatarUrl: userData.avatarUrl,
      gender: userData.gender || 0,
      country: userData.country || 'China',
      province: userData.province,
      city: userData.city,
      language: userData.language || 'zh_CN',
      phone: userData.phone,
      status: 1,
      loginCount: 1,
      lastLoginTime: new Date(),
      deviceInfo: userData.deviceInfo,
      createdTime: new Date(),
      updatedTime: new Date(),
    };

    // 使用 Sequelize 的 upsert 功能，避免两次数据库查询
    const [user, created] = await this.weixinUser.upsert(userCreateData, {
      returning: true,
    });

    // 如果是已存在用户，需要更新登录计数
    if (!created && user) {
      await user.update({
        sessionKey: userData.sessionKey || user.sessionKey,
        lastLoginTime: new Date(),
        loginCount: user.loginCount + 1,
        deviceInfo: userData.deviceInfo || user.deviceInfo,
        updatedTime: new Date(),
      });
      return user.reload();
    }

    return user;
  }

  /**
   * 更新用户基本信息
   */
  async updateUserInfo(
    openid: string,
    updateData: Partial<WeixinUserCreationAttributes>,
  ): Promise<WeixinUser | null> {
    const user = await this.findByOpenid(openid);
    if (!user) {
      return null;
    }

    await user.update({
      ...updateData,
      updatedTime: new Date(),
    });

    return user.reload();
  }

  /**
   * 根据ID查找用户
   */
  async findById(id: string): Promise<WeixinUser | null> {
    return await this.weixinUser.findByPk(id);
  }

  /**
   * 禁用/启用用户
   */
  async updateUserStatus(openid: string, status: number): Promise<boolean> {
    const [affectedCount] = await this.weixinUser.update(
      { status, updatedTime: new Date() },
      { where: { openid } },
    );

    return affectedCount > 0;
  }

  /**
   * 获取用户列表（分页）
   */
  async getUserList(
    page: number = 1,
    limit: number = 10,
    status?: number,
  ): Promise<{
    users: WeixinUser[];
    total: number;
    page: number;
    limit: number;
  }> {
    const offset = (page - 1) * limit;
    const whereCondition: Record<string, unknown> = {};

    if (status !== undefined) {
      whereCondition.status = status;
    }

    const { count, rows } = await this.weixinUser.findAndCountAll({
      where: whereCondition,
      limit,
      offset,
      order: [['lastLoginTime', 'DESC']],
    });

    return {
      users: rows,
      total: count,
      page,
      limit,
    };
  }
}
